use std::fs::File;
use std::io::{self, BufRead};
use std::{
    collections::HashMap,
    sync::{Arc, Mutex},
};

use crate::workflow::context::{Getter, WorkflowContext};
use model_graph_types::{
    container::workflow::{
        variables::WorkflowFileVariable, DocumentExtractorStatement, WorkflowBlockExecuteResult,
        WorkflowBlockExecuteResultBuilder, WorkflowBlockExecuteResultStatus,
    },
    modeling::Value,
};

pub async fn execute(
    statement: &DocumentExtractorStatement,
    context: Arc<Mutex<WorkflowContext>>,
) -> anyhow::Result<WorkflowBlockExecuteResult> {
    let result = _execute(statement, context).await;

    match result {
        Ok(v) => Ok(WorkflowBlockExecuteResultBuilder::default()
            .status(WorkflowBlockExecuteResultStatus::Succeeded)
            .source_handle("source")
            .result(v)
            .build()?),
        Err(err) => Ok(WorkflowBlockExecuteResultBuilder::default()
            .status(WorkflowBlockExecuteResultStatus::Succeeded)
            .source_handle("fail-branch")
            .build()?),
    }
}

pub async fn _execute(
    statement: &DocumentExtractorStatement,
    context: Arc<Mutex<WorkflowContext>>,
) -> anyhow::Result<HashMap<String, Value>> {
    let mut result: HashMap<String, Value> = HashMap::new();

    let inputs: Value = context.get_from_node(
        &statement.variable_selector.1,
        &statement.variable_selector.0,
    )?;

    if inputs.is_array() {
        //
    } else {
        let file: WorkflowFileVariable = inputs.try_into()?;
        //
        let file_path = &file.upload_file_id;
        let lines = io::BufReader::new(File::open(file_path)?).lines();
        let mut values = vec![];
        for line in lines {
            if let Ok(c) = line {
                values.push(Value::String(c));
            }
        }
        result.insert(String::from("text"), Value::Array(values));
    }
    //
    Ok(result)
}
